/*
 * AdminCustomerInfo.java
 *
 * Created on Jan 15, 2011, 4:01:19 PM
 */
package edu.rit.varapp.graphical;

import edu.rit.varapp.datalayer.Customer;
import edu.rit.varapp.datalayer.CustomerOps;
import edu.rit.varapp.utilities.ExceptionUtils;
import edu.rit.varapp.utilities.JTableUtils;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import static edu.rit.varapp.utilities.StringUtils.emptyString;
import static edu.rit.varapp.utilities.ValidationUtils.*;

/**
 *
 * @author Eric Kisner
 */
public class AdminCustomerInfo extends AbstractView {

    private static final int VIEW_WIDTH = 826;
    private static final int VIEW_HEIGHT = 585;
    private final CustomerOps cOps = new CustomerOps();
    private JTable customerTable = null;
    private int entityId;

    /** Creates new form AdminCustomerInfo */
    public AdminCustomerInfo() {
        super( new Dimension( VIEW_WIDTH, VIEW_HEIGHT ) );
        initComponents();
    }

    private void setCustomerTable( JTable customerTable ) {
        this.customerTable = customerTable;
    }

    private void setEntityId( int entityId ) {
        this.entityId = entityId;
    }

    /**
     * Get any Customer information associated with the specified customer name.
     * @param customerName The customer's name whose information we're looking for. There could be multiple people
     *                     with the same name.
     */
    private void showCustomers( String customerName ) {
        ArrayList<Customer> customers = null;
        try {
            customers = cOps.retrieveCustomers( customerName );
        } catch( SQLException sqle ) {
            ExceptionUtils.handleException( this, sqle, "There was a problem trying to retrieve customers with the "
                                                        + "name '" + customerName + "'. Please check the log files "
                                                        + "for more details.", this.getClass() );
            return;
        }
        String[] header = { "Title", "Contact Name", "Company Name", "Email" };
        JTable table = JTableUtils.getCustomerTable( header, customers, false );
        table = applyOptions( table );
        setCustomerTable( table );
        JScrollPane holder = new JScrollPane( table );
        mainPanel.add( holder );
        holder.setBounds( 0, 0, 780, 180 );
    }

    /**
     * Apply any options to the dynamically created JTable.
     */
    private JTable applyOptions( final JTable table ) {
        final ArrayList<ArrayList<String>> data = JTableUtils.dataFromTable( table );
        table.setRowHeight( 30 );
        table.setRowMargin( 10 );
        table.setSelectionMode( javax.swing.ListSelectionModel.SINGLE_SELECTION );
        table.getSelectionModel().addListSelectionListener( new ListSelectionListener() {

            public void valueChanged( ListSelectionEvent lse ) {
                //Since the table uses single_selection, there can only be one row selected at a time
                final int curRow = table.getSelectionModel().getLeadSelectionIndex();
                //Get the customer information of the current selected row
                ArrayList<String> customerData = data.get( curRow );
                //Get the EntityId of the selected customer by using their company name and contact name
                try {
                    int entityId = cOps.retrieveCustomer( customerData.get( 1 ), customerData.get( 2 ) ).getEntityId();
                    setEntityId( entityId );
                    showFields();
                } catch( SQLException sqle ) {
                    ExceptionUtils.handleException( AdminCustomerInfo.this, sqle,
                                                    "There was a problem trying to retrieve customer "
                                                    + "information for " + customerData.get( 1 ) + ".\n"
                                                    + "Please check the log files for more information.",
                                                    this.getClass() );
                    return;
                }
            }
        } );
        table.setShowHorizontalLines( false );
        table.setShowVerticalLines( false );
        return table;
    }

    /**
     * Display all customer information in the text fields for the selected customer.
     */
    private void showFields() {
        resetFields();
        try {
            Customer customer = cOps.retrieveCustomer( entityId );
            nameField.setText( customer.getContactName() );
            companyField.setText( customer.getCompanyName() );
            titleField.setText( customer.getTitle() );
            stateField.setText( customer.getState() );
            zipField.setText( customer.getZipcode() );
            address2Field.setText( customer.getAddr2() );
            addressField.setText( customer.getAddr1() );
            cityField.setText( customer.getCity() );
            emailField.setText( customer.getEmail() );
            entityidField.setText( String.valueOf( entityId ) );
        } catch( SQLException sqle ) {
            ExceptionUtils.handleException( this, sqle,
                                            "There was an error retrieving information for customer with "
                                            + "entityId [" + entityId + "]. Please check the log files for "
                                            + "more information.",
                                            this.getClass() );
            return;
        }
    }

    /**
     * Refreshes this GUI by re-displaying the customer table, as well as resetting all fields.
     */
    private void refreshGUI() {
        resetFields();
        if( customerTable != null ) {
            mainPanel.removeAll();
        }
        showCustomers( customerNameField.getText() );
        this.repaint();
        this.validate();
    }

    /**
     * Resets any text field on the GUI
     */
    private void resetFields() {
        nameField.setText( "" );
        companyField.setText( "" );
        titleField.setText( "" );
        stateField.setText( "" );
        zipField.setText( "" );
        address2Field.setText( "" );
        addressField.setText( "" );
        cityField.setText( "" );
        emailField.setText( "" );
        entityidField.setText( "" );
    }

    /**
     * Validates any input for the text fields of this GUI.
     * @return True if all fields are valid, else false.
     */
    private boolean validateInput() {
        String[] methodNames = {
            "NumLength", "VarCharLength", "Title", "Name", "Email",
            "Char", "State", 
        };
        String[] messages = {
            "Entity ID (Digits only)", "Company Name", "Title (ex. Mr/Ms)",
            "Contact Name (ex. John Smith)","Email Address (test@test.com)",
            "City", "State (ex. NY)",
        };
        String[] values = {
            entityidField.getText(), companyField.getText(), titleField.getText(), nameField.getText(),
            emailField.getText(), cityField.getText(), stateField.getText()
        };

        String errorMessage = runValidateMethodList( Arrays.asList( methodNames ),
                                                     Arrays.asList( messages ),
                                                     Arrays.asList( values ) );
        if( errorMessage.equals( emptyString() ) ) {
            return true;
        } else {
            JOptionPane.showMessageDialog( rootPane, errorMessage );
            return false;
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings( "unchecked" )
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        applyChangesButton = new javax.swing.JButton();
        mainPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        entityidField = new javax.swing.JTextField();
        jLabel12 = new javax.swing.JLabel();
        titleField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        nameField = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        companyField = new javax.swing.JTextField();
        jLabel11 = new javax.swing.JLabel();
        emailField = new javax.swing.JTextField();
        jPanel2 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        addressField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        address2Field = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        cityField = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        stateField = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        zipField = new javax.swing.JTextField();
        backButton = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        customerNameField = new javax.swing.JTextField();
        getCustomerInformationButton = new javax.swing.JButton();
        deleteCustomerButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Customer Information");
        setMinimumSize(new java.awt.Dimension(821, 580));
        setResizable(false);
        getContentPane().setLayout(null);

        applyChangesButton.setText("Apply Changes");
        applyChangesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                applyChangesButtonActionPerformed(evt);
            }
        });
        getContentPane().add(applyChangesButton);
        applyChangesButton.setBounds(100, 520, 180, 23);

        mainPanel.setLayout(null);
        getContentPane().add(mainPanel);
        mainPanel.setBounds(20, 60, 780, 180);

        jPanel1.setLayout(new java.awt.GridLayout(5, 2, 0, 15));

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel2.setText("EntityId:");
        jPanel1.add(jLabel2);
        jPanel1.add(entityidField);

        jLabel12.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel12.setText("Title:");
        jPanel1.add(jLabel12);
        jPanel1.add(titleField);

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel4.setText("Name:");
        jPanel1.add(jLabel4);
        jPanel1.add(nameField);

        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel5.setText("Company:");
        jPanel1.add(jLabel5);
        jPanel1.add(companyField);

        jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel11.setText("Email:");
        jPanel1.add(jLabel11);
        jPanel1.add(emailField);

        getContentPane().add(jPanel1);
        jPanel1.setBounds(30, 290, 300, 220);

        jPanel2.setLayout(new java.awt.GridLayout(5, 2, 0, 15));

        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel6.setText("Address:");
        jPanel2.add(jLabel6);
        jPanel2.add(addressField);

        jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel7.setText("Address 2:");
        jPanel2.add(jLabel7);
        jPanel2.add(address2Field);

        jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel8.setText("City:");
        jPanel2.add(jLabel8);
        jPanel2.add(cityField);

        jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel9.setText("State:");
        jPanel2.add(jLabel9);

        stateField.setColumns(2);
        jPanel2.add(stateField);

        jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        jLabel10.setText("Zip:");
        jPanel2.add(jLabel10);
        jPanel2.add(zipField);

        getContentPane().add(jPanel2);
        jPanel2.setBounds(400, 290, 340, 220);

        backButton.setText("Back");
        backButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                backButtonActionPerformed(evt);
            }
        });
        getContentPane().add(backButton);
        backButton.setBounds(500, 520, 180, 23);

        jPanel3.setLayout(new java.awt.GridLayout(1, 3, 2, 0));

        jLabel1.setText("Enter Customer Name:");
        jPanel3.add(jLabel1);

        customerNameField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                customerNameFieldKeyPressed(evt);
            }
        });
        jPanel3.add(customerNameField);

        getCustomerInformationButton.setText("Get Customer Information");
        getCustomerInformationButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getCustomerInformationButtonActionPerformed(evt);
            }
        });
        jPanel3.add(getCustomerInformationButton);

        getContentPane().add(jPanel3);
        jPanel3.setBounds(30, 10, 590, 30);

        deleteCustomerButton.setText("Delete Customer");
        deleteCustomerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteCustomerButtonActionPerformed(evt);
            }
        });
        getContentPane().add(deleteCustomerButton);
        deleteCustomerButton.setBounds(300, 520, 180, 23);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void getCustomerInformationButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_getCustomerInformationButtonActionPerformed
    {//GEN-HEADEREND:event_getCustomerInformationButtonActionPerformed
        refreshGUI();
    }//GEN-LAST:event_getCustomerInformationButtonActionPerformed

    private void applyChangesButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_applyChangesButtonActionPerformed
    {//GEN-HEADEREND:event_applyChangesButtonActionPerformed
        if( validateInput() ) {
            int newEntityId = Integer.parseInt( entityidField.getText() );
            Customer customer = new Customer( newEntityId, titleField.getText(), nameField.getText(),
                                              companyField.getText(), addressField.getText(),
                                              address2Field.getText(), cityField.getText(),
                                              stateField.getText(), zipField.getText(),
                                              emailField.getText() );
            try {
                cOps.updateCustomer( customer, entityId );
                JOptionPane.showMessageDialog( rootPane, "Successfully updated information for customer "
                                                         + customer.getContactName() + "." );
                refreshGUI();
            } catch( SQLException sqle ) {
                ExceptionUtils.handleException( this, sqle, "There was a problem updating information for customer "
                                                            + customer.getContactName(), this.getClass() );
                return;
            }
        }
    }//GEN-LAST:event_applyChangesButtonActionPerformed

    private void backButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_backButtonActionPerformed
    {//GEN-HEADEREND:event_backButtonActionPerformed
        new AdminOperations().setVisible( true );
        close( false );
    }//GEN-LAST:event_backButtonActionPerformed

    private void customerNameFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_customerNameFieldKeyPressed
        if( evt.getKeyCode() == KeyEvent.VK_ENTER ) {
            refreshGUI();
        }
    }//GEN-LAST:event_customerNameFieldKeyPressed

    private void deleteCustomerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteCustomerButtonActionPerformed
        try {
            Customer toDelete = cOps.retrieveCustomer( entityId );
            boolean success = cOps.deleteCustomer( toDelete );
            if( success ) {
                JOptionPane.showMessageDialog( rootPane, "Successfully deleted customer " + toDelete.getContactName() );
                refreshGUI();
            }
        } catch( SQLException sqle ) {
            ExceptionUtils.handleException( this, sqle, "Problem retrieving the customer. "
                                                        + "Please check the log files for more information.",
                                            this.getClass() );
            return;
        }
    }//GEN-LAST:event_deleteCustomerButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField address2Field;
    private javax.swing.JTextField addressField;
    private javax.swing.JButton applyChangesButton;
    private javax.swing.JButton backButton;
    private javax.swing.JTextField cityField;
    private javax.swing.JTextField companyField;
    private javax.swing.JTextField customerNameField;
    private javax.swing.JButton deleteCustomerButton;
    private javax.swing.JTextField emailField;
    private javax.swing.JTextField entityidField;
    private javax.swing.JButton getCustomerInformationButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JTextField nameField;
    private javax.swing.JTextField stateField;
    private javax.swing.JTextField titleField;
    private javax.swing.JTextField zipField;
    // End of variables declaration//GEN-END:variables
}
